﻿using System;
using System.Linq;
using System.Security.Cryptography;
using Grundy.CryptographicServices;
using Grundy.Entity;
using Grundy.Common;
using Grundy.Message;

namespace Grundy.Administration.Web.Services
{
    public class CustomerService
    {
        private readonly CryptographicServicesProvider _serverCryptographicServicesProvider;
        public EntitlementsDatabase Db { get; private set; }

        public CustomerService()
        {
            _serverCryptographicServicesProvider = Application.Instance.ServerCryptographicServicesProvider;
            Db = new EntitlementsDatabase("EntitlementsDatabase");
        }

        public CustomerService(CryptographicServicesProvider serverCryptographicServicesProvider)
        {
            _serverCryptographicServicesProvider = serverCryptographicServicesProvider;
            Db = new EntitlementsDatabase("EntitlementsDatabase");
        }

        public CustomerService(EntitlementsDatabase db, CryptographicServicesProvider serverCryptographicServicesProvider)
        {
            _serverCryptographicServicesProvider = serverCryptographicServicesProvider;
            Db = db;
        }

        public IQueryable<Customer> GetCustomers(int page = 1, int pageSize = 0)
        {
            if (page == 1 && pageSize == 0)
                return Db.Customers.OrderBy(i => i.Name);
            return Db.Customers.OrderBy(i => i.Name).Skip((page - 1) * pageSize).Take(pageSize);
        }

        public Customer GetCustomer(Guid id)
        {
            return Db.Customers.Find(id);
        }

        public Customer GetCustomer(string name)
        {
            return Db.Customers.FirstOrDefault(f => f.Name == name);
        }

        public Customer CreateCustomer(string name)
        {
            var buffer = new byte[64];
            new RNGCryptoServiceProvider().GetNonZeroBytes(buffer);
            var encryptedKey = _serverCryptographicServicesProvider.EncryptData(buffer);

            var customer = new Customer { Name = name, Key = encryptedKey.ToHexadecimalString()};
            Db.Customers.Add(customer);
            Db.SaveChanges();
            return customer;
        }

        public string GetCustomerKey(Guid customerId)
        {
            var customer = Db.Customers.Find(customerId);
            var encryptedKey = customer.Key;
            var decryptedKey = _serverCryptographicServicesProvider.DecryptData(encryptedKey.ToByteArray());
            return decryptedKey.ToHexadecimalString();
        }
    }
}